﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Fleck;
using Newtonsoft.Json;
using System.Configuration;


namespace RobotWebSocketApp
{
    class WebSocketServerManager
    {
        /*
         * Web Socket server 函数运行主体
         */
        WebSocketServer server;
        /*
         * Fanuc Robot 机器人模型
         */
        FanucRobotInf fanucRobotInf;

        public WebSocketServerManager()
        {

        }

        public void ServerInit()
        {
            FleckLog.Level = LogLevel.Debug;
            string serverAddress = "ws://" + ConfigurationManager.AppSettings["ServerIP"] + ":" + ConfigurationManager.AppSettings["ServerPort"];
            server = new WebSocketServer(serverAddress);
            fanucRobotInf = new FanucRobotInf();
        }

        public void ServerRun()
        { 
            var allSockets = new List<IWebSocketConnection>();
            // Server 服务启动
            server.Start(socket =>
            {
                socket.OnOpen = () =>
                {
                    Console.WriteLine("Open!");
                    allSockets.Add(socket);
                };

                socket.OnClose = () =>
                {
                    Console.WriteLine("Close!");
                    allSockets.Remove(socket);
                };

                socket.OnMessage = message =>
                {
                    // 解析数据采集任务
                    TaskInf taskInf = JsonConvert.DeserializeObject<TaskInf>(message);

                    // 记录数据采集开始时间
                    double dblTime = GflngGetTickCountEx();

                    // 设置机器人通信 IP 地址信息
                    fanucRobotInf.SetHostName(taskInf.RobotIP);

                    // 设置机器人通信 超时时间
                    fanucRobotInf.SetTimeOutValue(taskInf.TimeOutValue);
                    taskInf.TaskResult = new List<string>();
                    List<string> strResult;
                    strResult = taskInf.TaskResult;
                    string strResultMessage = "";

                    switch (taskInf.TaskName)
                    {
                        case "GetTask":
                        {
                            taskInf.Result = fanucRobotInf.GetTask(taskInf.TaskType.TypeName, short.Parse(taskInf.TaskType.TypePara), 
                                                                    ref strResult, ref strResultMessage);                                     
                            break;
                        }

                        case "ReadPos":
                        {
                            taskInf.Result = fanucRobotInf.GetCurPos(taskInf.TaskType.TypeName,short.Parse(taskInf.TaskType.TypePara),
                                                                    taskInf.TaskType.TypeNumber, 
                                                                    ref strResult, ref strResultMessage);
                            break;
                        }

                        case "GetSysVariable":
                        {
                            taskInf.Result = fanucRobotInf.GetSysVar(taskInf.TaskType.TypeName,taskInf.TaskType.TypePara,
                                                                    ref strResult, ref strResultMessage);                     
                            break;
                        } 

                        case "ReadIO":
                        {
                            taskInf.Result = fanucRobotInf.ReadIO(taskInf.TaskType.TypeName,short.Parse(taskInf.TaskType.TypePara), 
                                                                    taskInf.TaskType.TypeNumber, 
                                                                    ref strResult, ref strResultMessage);
                            break;
                        }

                        case "ReadAlarm":
                        {
                            taskInf.Result = fanucRobotInf.ReadAlarm(short.Parse(taskInf.TaskType.TypePara), 
                                                                    taskInf.TaskType.TypeNumber, 
                                                                    ref strResult, ref strResultMessage);
                            break;
                        }

                        case "GetStringReg":
                        {
                            taskInf.Result = fanucRobotInf.GetStringReg(short.Parse(taskInf.TaskType.TypePara), 
                                                                    taskInf.TaskType.TypeNumber, 
                                                                    ref strResult, ref strResultMessage); 
                            break;
                        }

                        case "GetPosReg":
                        {
                            taskInf.Result = fanucRobotInf.GetPosReg(taskInf.TaskType.TypeName, short.Parse(taskInf.TaskType.TypePara), 
                                                                    taskInf.TaskType.TypeNumber, 
                                                                    ref strResult, ref strResultMessage);
                            break;
                        }
                                                
                        case "GetNumberReg":
                        {
                            taskInf.Result = fanucRobotInf.GetNumberReg(taskInf.TaskType.TypeName,short.Parse(taskInf.TaskType.TypePara), 
                                                                    taskInf.TaskType.TypeNumber, 
                                                                    ref strResult, ref strResultMessage);
                            break;
                        }

                        default:
                        {
                            taskInf.Result = false;
                            strResultMessage = "Please input the task name!";
                            break;
                        }
                    }
                    taskInf.ResultMessage = strResultMessage;
                    // 记录数据采集停止时间
                    dblTime = GflngGetTickCountEx() - dblTime;
                    taskInf.TimeOutValue = Convert.ToInt16(dblTime);
                    // 返回采集 Json 数据
                    socket.Send(JsonConvert.SerializeObject(taskInf));
                };
            });
        }

        public long GflngGetTickCountEx()
        {
            // return tick count[ms]
            return System.DateTime.Now.Ticks / System.TimeSpan.TicksPerMillisecond;
        }
    }
}
